﻿using System;
using System.Diagnostics;
using System.IO.Ports;
namespace RFIDReader
{
    public class TTPReader
    {
        public TTPReader(SerialPort sp)
        {
            thePort = sp;
        }
        ~TTPReader()
        {
            Close();
        }
        public bool Open()
        {
            var pn = thePort.PortName.Remove(0,3);
            comport = uint.Parse(pn);

            bool ret = Open(0, comport, thePort.BaudRate);

            if (readerID == 0)
                UpdateReaderID();

            return last == MResponse.LIB_SUCCESS;
        }
        private bool Open(ushort rid, uint com, int baud)
        {
            last = MasterRD.rf_COM_Open(com, baud);
            Console.WriteLine("ComOpen:{0}", last);
            if (last != MResponse.LIB_SUCCESS)
                return false;
            last = MasterRD.rf_Reader_ComOpen(com, rid);
            Console.WriteLine("ReaderOpen:{0}", last);
            if (last != MResponse.LIB_SUCCESS)
                return false;

            return true;
        }
        private void UpdateReaderID()
        {
            ushort rid = 0;
            last = MasterRD.rf_Reader_GetID(ref rid);
            readerID = (ushort)((rid >> 0x08) & 0xff);
            readerID += (ushort)((rid << 0x08) & 0xff00);
            Console.WriteLine("Retrieved ReaderID:{0}", readerID.ToString("X4"));
            Close(0, comport);

            Open(readerID, comport, thePort.BaudRate);
        }
        public void Close()
        {
            Close(readerID, comport);
        }
        private void Close(ushort rid, uint com)
        {
            last = MasterRD.rf_Reader_Close(rid);
            Console.WriteLine("rf_Reader_Close:{0}", last);
            last = MasterRD.rf_COM_Close(com);
            Console.WriteLine("rf_COM_Close:{0}", last);
        }
        public override int GetHashCode()
        {
            return (int)readerID;
        }
        private SerialPort thePort;
        private ushort readerID = 0;
        private uint comport;
        private MResponse last;

        public bool SelectMifareClassicCard(int timeout, RequestMode WAK)
        {
            return false;
            //return MasterRD.SelectSpecificCard(readerID, timeout, WAK, MIFARE_CLASSIC);
        }
        public MResponse ReadMifareClassicCard()
        {//Doesn't work right now. No SAM card used for test
            byte[] pData = new byte[16];
            for (byte i = 0x00; i < 0xFF; i++)
            {
                //absolute block number to read; 0x00 - 0x3F for Mifare S50; 0x00 - 0xFF for Mifare S70
                last = MasterRD.rf_M1_Read(readerID, i, pData);
                Console.WriteLine("ReadM1:{0}: {1}", last, BitConverter.ToString(pData));
            }
            return last;
        }
        public bool SelectMifareULCCard(int timeout, RequestMode WAK)
        {
            iPublicEntity ipe = new UltraLightCPublicEntity();
            return ipe.SelectCard(readerID, timeout, WAK);
        }
        public MResponse ReadMifareULCCard()
        {//Doesn't work right now. No SAM card used for test

            //byte[] pcAPDU = new byte[16] { 0x8A, 0x9E, 0xE2, 0x68, 0x8E, 0xA2, 0xDE, 0xA6, 0xB0, 0x8C, 0xBE, 0x32, 0x3C, 0xAF, 0x0E, 0xFE };
            //last = MasterRD.rf_UltraLightC_Authentication(readerID, pcAPDU);
            //for (byte i = 22; i <= 34; i += 4)
            //{
            //    last = MasterRD.rf_UltraLight_Read(readerID, i, pData);
            //    Console.WriteLine("ReadULCS:{0}: {1}", last, BitConverter.ToString(pData));
            //}
            //MasterRD.rf_UltraLight_Read(readerID, (byte)40, pData);
            //Console.WriteLine("ReadULCS:{0}: {1}", last, BitConverter.ToString(pData));
            //MasterRD.rf_UltraLight_Read(readerID, (byte)44, pData);
            //Console.WriteLine("ReadULCS:{0}: {1}", last, BitConverter.ToString(pData));
            return last;
        }
        public bool SelectMifareDesfireCard(int timeout, RequestMode WAK)
        {
            return false;// MasterRD.SelectSpecificCard(readerID, timeout, WAK, MIFARE_DESFIRE);
        }
        public MResponse GetDesfireApplications()
        {
            Console.WriteLine("+GetDesfireApplications");
            MasterRD.SelectDesfireSelectApplication(readerID, new byte[3]);
            MasterRD.GetDesfireApplications(readerID);
            Console.WriteLine("-GetDesfireApplications:{0}", last);
            return last;
        }
        public void Halt()
        {
            last = MasterRD.rf_ISO14443A_Halt(readerID);
            Console.WriteLine("Halt:{0}", last);
        }
        }
}
